#include "my.h"

typedef struct
{
	int type;//请求的类型
	char username[50];//用户名
	char passwd[50];//用户密码
	char filename[50];
	char filedata[100];
	int size;
}data_t;

int flag = 0;//0代表当前显示菜单1, 3代表显示菜单界面二
char loginName[50];

//给服务器发送的注册请求函数
void registerRequest(int sockfd)
{
	//1.定义一个结构体变量装上　请求类型 用户名 密码
	data_t s = { 0 };
	s.type = 1;//1 代表注册请求
	printf("请您输入要注册的用户名和密码:\n");
	scanf("%s%s",s.username, s.passwd);
	//2.将请求　用户名和密码发送给服务器
	send(sockfd, &s, sizeof(s), 0);
	//3.阻塞接收服务器的应答
	recv(sockfd, &s, sizeof(s), 0);
	if(s.type == 0)
		printf("恭喜%s,注册成功!!\n",s.username);
	else if(s.type == -1)
		printf("非常抱歉%s, 用户名已经被注册!!!\n",s.username);
	
}
//给服务器发送的登录请求函数
void loginRequest(int sockfd)
{
	//1.定义一个结构体变量装上　请求类型 用户名 密码
	data_t s = { 0 };
	s.type = 2;//2 代表登录请求
	printf("请您输入要登录的用户名和密码:\n");
	scanf("%s%s",s.username, s.passwd);
	//2.将请求　用户名和密码发送给服务器
	send(sockfd, &s, sizeof(s), 0);
	//3.阻塞接收服务器的应答
	recv(sockfd, &s, sizeof(s), 0);
	//4.对登录结果帕判断
	if(s.type == -1)
		printf("登录的用户名不存在!!!!!\n");
	else if(s.type == -2)
		printf("登录的密码错误!!!\n");
	else if(s.type == 0)
	{
		strcpy(loginName,s.username);
		flag = 3;
		printf("登录成功!!!\n");
	}
}

void getListRequest(int sockfd)
{
	data_t s = { 0 };
	s.type = 3;
	strcpy(s.username,loginName);
	send(sockfd,&s,sizeof(s),0);
	while(1)
	{
		recv(sockfd,&s,sizeof(s),0);
		if(s.type == 0)
			break;
		printf("%s    ",s.filename);
	}
	printf("\n ");
}

void upLoadRequest(int sockfd)
{
	char pathName[100];
	char dirName[50];
	data_t s = { 0 };
	s.type = 4;
	strcpy(s.username,loginName);
	printf("请您输入要上传的文件所在目录的绝对路径:\n");
	scanf("%s",dirName);
	printf("请输入要上传文件的名字:\n");
	scanf("%s",s.filename);
	sprintf(pathName,"%s/%s",dirName,s.filename);
	int fd = open(pathName,O_RDONLY);
	if(fd == -1)
	{
		perror("open failed");
		return;
	}
	while((s.size = read(fd,s.filedata,sizeof(s.filedata))) > 0)
	{
		send(sockfd,&s,sizeof(s),0);
		usleep(10*1000);
	}
	s.size = -1;
	send(sockfd,&s,sizeof(s),0);
	printf("%s上传完毕！！！\n",s.filename);
	close(fd);
}

void downLoadRequest(int sockfd)
{
	char dirName[100] = { 0 };
	char pathName[100];
	data_t s = { 0 };
	s.type = 5;
	strcpy(s.filename,loginName);
	printf("请输入要下载文件的名字");
	scanf("%s",s.filename);
	printf("请输入要将下载文件保存的位置：\n");
	scanf("%s",dirName);
	sprintf(pathName,"%s/%s",dirName,s.filename);
	send(sockfd,&s,sizeof(s),0);
	recv(sockfd,&s,sizeof(s),0);
	if(s.size == -1)
		printf("下载的%s不存在！！\n",s.filename);
	else
	{
		printf("下载的%s存在！！\n",s.filename);
		int fd = open(pathName,O_WRONLY|O_CREAT|O_TRUNC,0666);
		if(fd == -1)
		{
			perror("open failed");
			exit(-1);
		}
		while(1)
		{
			recv(sockfd,&s,sizeof(s),0);
			if(s.size == -2)
			{
				printf("%s下载完毕!!\n",s.filename);
				close(fd);
				break;
			}
			write(fd,s.filedata,s.size);
		}
	}
}

void getHistoryInfoRequest(int sockfd)
{
	data_t s = { 0 };
	s.type = 6;
	strcpy(s.username,loginName);
	send(sockfd,&s,sizeof(s),0);
	while(1)
	{
		recv(sockfd,&s,sizeof(s),0);
		if(s.type == -1)
			break;
		printf("%s\n",s.filedata);
	}
}

//菜单界面
void showMenu()
{
		if(flag == 0)
		{
			printf("\n****************************************\n");
			printf("*            小   度   网   盘           *");
			printf("\n****************************************\n");
			printf("\n*      1.注册    2.登录    3.退出      *\n");
			printf("\n****************************************\n");
			printf("\n请 输 入 您 的 选 择:\n\n");
		}
		else if(flag == 3)
		{
			printf("\n/////////////////////////////////////////////////////");
			printf("\n*****************************************************\n");
			printf("*           欢　迎　使　用　小  度  网   盘  　    *");
			printf("\n*****************************************************\n");
			printf("\n* 1.列表  2.上传文件  3.下载文件 4.历史记录  5.退出*\n"); //4 5 6 7 8
			printf("\n*****************************************************\n");
			printf("/////////////////////////////////////////////////////\n");
			printf("\n请 输 入 您 的 选 择:\n\n");
		}
}

int main(int argc, const char *argv[])
{
	int choose;
	//1.创建流式套接字
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd == -1)
	{
		perror("socket failed");
		exit(-1);
	}
	//2.连接服务器
	struct sockaddr_in toaddr = { 0 };
	toaddr.sin_family = AF_INET;
	toaddr.sin_port = htons(6666);//端口号
	toaddr.sin_addr.s_addr = inet_addr("192.168.8.19");//根据服务器的IP进行修改
	connect(sockfd, (struct sockaddr*)&toaddr, sizeof(toaddr));
	//3.发送数据给服务器端
	while(1)
	{
		showMenu();//显示菜单
		scanf("%d",&choose);
		if(flag == 0 && choose > 3)
		{
			printf("输入的选择不合理,请重新输入选择!!!\n");
			continue;
		}
		switch(choose+flag)
		{
		case 1://注册请求
			registerRequest(sockfd);//给服务器发送一个注册请求
			break;
		case 2://登录请求
			loginRequest(sockfd);//给服务器发送一个登录请求
			break;
		case 3://退出客户端
			printf("欢迎下次使用!! 3s后结束程序!!\n");
			sleep(3);
			exit(0);
		case 4://获取列表请求
			getListRequest(sockfd);
			break;
		case 5://上传
			upLoadRequest(sockfd);
			break;
		case 6://下载文件
			downLoadRequest(sockfd);
			break;
		case 7:
			getHistoryInfoRequest(sockfd);
			break;
		}
	}
	return 0;
}